(function(w) {
    function deepClone(target, obj) {
        if (typeof target !== 'object') {
            target = {};
        }
        if (typeof obj !== 'object') {
            obj = {};
        }
        for (var i in obj) {
            if (typeof obj[i] === 'object') {
                target[i] = deepClone(target[i], obj[i]);
            } else {
                target[i] = obj[i];
            }
        }
        return target;
    }

    function empty(val) {
        if (val instanceof Array) {
            return val.length <= 0;
        } else if (typeof val === 'object') {
            for (let i in val) {
                return false;
            }
            return true;
        } else {
            return !val;
        }
    }

    function trackSlide(config) {
        // this.init();
        if (this === w) {
            throw new Error('Error: new trackSlide');
        }
        let data = {
            data: {},
            config: {},
            el: {
                wrap: null,
                track: null,
                slide: null
            },
            eventList: {
                move: []
            },
            left: 0,
            startX: null,
            position: 0
        }
        for (let i in data) {
            this[i] = data[i];
        }
        this.init(config);
        return this;
    }
    trackSlide.prototype = {
        constructor: trackSlide,
        version: '1.0',
        getEl(name) {
            if (name) {
                return this.el[name] || null
            } else {
                return this.el;
            }
        },
        init(config) {
            if (empty(config) || !config.wrap || !config.track || !config.slide) {
                throw new Error('缺少配置信息');
            }
            this.config = config;
            let el = {
                wrap: document.querySelector(config.wrap)
            };
            if (empty(el.wrap)) {
                throw new Error('wrap元素不存在');
            }
            let trackEl = document.createElement('div');
            trackEl.classList.add(config.track.replace(/^[.#]{1}/, ''));
            el.wrap.appendChild(trackEl);
            let slideEl = document.createElement('div');
            slideEl.classList.add(config.slide.replace(/^[.#]{1}/, ''));
            slideEl.title = this.position;
            trackEl.appendChild(slideEl);
            el.track = trackEl;
            el.slide = slideEl;
            this.el = el;
            this.pcEvent();
            this.mobileEvent();
        },
        // PC端move事件
        mouseMove(e) {
            let offset = e.screenX - this.startX;
            offset = offset + this.left;
            this.move.call(this, e, offset);
        },
        //移动端move事件
        touchMove(e) {
            let offset = e.changedTouches[0].clientX - this.startX;
            offset = offset + this.left;
            this.move.call(this, e, offset)
        },
        // 核心move事件
        move(e, offset) {
            if (offset <= 0) {
                this.el.slide.style.left = 0;
            } else if (offset <= this.el.track.clientWidth) {
                this.el.slide.style.left = offset + 'px';
            }
            this.eventList.move.forEach((el, index) => {
                // console.log(this.el.slide.style.left, this.el.track.clientWidth);
                this.position = Math.round((this.el.slide.style.left.replace(/[a-zA-Z]*$/, '') / this.el.track.clientWidth) * 100);
                this.el.slide.title = this.position;
                el.call(this, this.position, e, this.el);
            });
        },
        pcEvent() {
            let mouseMove = this.mouseMove.bind(this);
            this.el.slide.addEventListener('mousedown', e => {
                this.el.slide.classList.add('on');
                this.startX = e.screenX;
                this.left = parseFloat(this.el.slide.style.left) || 0;
                document.addEventListener('mousemove', mouseMove);
            });
            document.addEventListener('mouseup', e => {
                this.el.slide.classList.remove('on');
                document.removeEventListener('mousemove', mouseMove);
                this.startX = null;
            });
        },
        mobileEvent() {
            this.el.slide.addEventListener('touchstart', e => {
                this.el.slide.classList.add('on');
                this.startX = e.changedTouches[0].clientX;
                this.left = parseFloat(this.el.slide.style.left) || 0;
            });
            this.el.slide.addEventListener('touchmove', this.touchMove.bind(this));
            this.el.slide.addEventListener('touchend', e => {
                this.el.slide.classList.remove('on');
                this.startX = null;
            });
        },
        on(eventName, callback) {
            if (eventName in this.eventList && Array.isArray(this.eventList[eventName]) && typeof callback === 'function') {
                this.eventList[eventName].push(callback);
            }
        }
    };
    w.trackSlide = trackSlide;
})(window);